package cn.iocoder.yudao.module.system.controller.admin.ai;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.system.controller.admin.normalquestioncontent.vo.NormalQuestionContentRespVO;
import cn.iocoder.yudao.module.system.dal.dataobject.normalquestioncontent.NormalQuestionContentDO;
import cn.iocoder.yudao.module.system.service.normalquestioncontent.NormalQuestionContentService;
import cn.iocoder.yudao.module.system.service.user.UserAssetsService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import java.nio.charset.StandardCharsets;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import java.io.InputStreamReader;
import org.springframework.core.io.ClassPathResource;
import java.io.InputStream;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.util.ArrayList;
import java.util.List;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

/**
 * @author zhaoying
 */
@RestController
@RequestMapping("/system/majors/data")
public class MajorsDataController {
    @Resource
    private NormalQuestionContentService normalQuestionContentService;

    @Resource
    private UserAssetsService userAssetsService;
    @RequestMapping("/get")
    @PermitAll
    public CommonResult<String> getMajorsData(@RequestParam(required = false) String name) {
        String majorsData = readResourceFile("majors.properties", "majors.data");

        // If name parameter is not provided, return all majors data
        if (name == null || name.trim().isEmpty()) {
            return success(majorsData);
        }

        // Perform fuzzy search by major name
        try {
            ObjectMapper mapper = new ObjectMapper();
            JsonNode rootNode = mapper.readTree(majorsData);
            JsonNode bodyNode = rootNode.get("body");

            if (bodyNode != null && bodyNode.isArray()) {
                List<JsonNode> filteredMajors = new ArrayList<>();
                searchMajorsByName(bodyNode, name.toLowerCase(), filteredMajors);

                // Create a new JSON structure with the filtered results
                ObjectMapper resultMapper = new ObjectMapper();
                ObjectNode resultRoot = resultMapper.createObjectNode();
                resultRoot.put("code", rootNode.get("code").asInt());
                resultRoot.put("msg", rootNode.get("msg").asText());
                resultRoot.set("body", resultMapper.valueToTree(filteredMajors));

                return success(resultMapper.writeValueAsString(resultRoot));
            }

            return success(majorsData); // Return all data if JSON structure is unexpected
        } catch (Exception e) {
            e.printStackTrace();
            return success(majorsData); // Return all data in case of error
        }
    }

    /**
     * Recursively search majors by name
     *
     * @param node The current JSON node to search in
     * @param searchTerm The lowercase search term
     * @param results List to collect matching results
     */
    private void searchMajorsByName(JsonNode node, String searchTerm, List<JsonNode> results) {
        if (node.isArray()) {
            for (JsonNode item : node) {
                // Check if this item matches the search term
                JsonNode nameNode = item.get("name");
                boolean matches = false;

                if (nameNode != null && !nameNode.isNull()) {
                    String majorName = nameNode.asText().toLowerCase();
                    if (majorName.contains(searchTerm)) {
                        matches = true;
                        results.add(item);
                    }
                }

                // Even if this node matches, still check its children for matches
                JsonNode children = item.get("children");
                if (children != null && !children.isNull() && children.isArray()) {
                    // If parent already matched, don't need to search children separately
                    if (!matches) {
                        searchMajorsByName(children, searchTerm, results);
                    }
                }
            }
        }
    }

    /**
     * Get major detail by ID
     *
     * @return Major detail information
     */
    @GetMapping("/detail")
    @PermitAll
    public CommonResult<NormalQuestionContentRespVO> getMajorDetail(@RequestParam(required = false)String majorName) {
        // 获取当前登录用户ID
        Long userId = SecurityFrameworkUtils.getLoginUserId();

        // 检查用户内容会员剩余次数
//        userAssetsService.validateUserContentMembership(userId);

        NormalQuestionContentDO normalQuestionContentDO = normalQuestionContentService.getNormalQuestionContentByName(majorName);
        return success(BeanUtils.toBean(normalQuestionContentDO, NormalQuestionContentRespVO.class));
    }

    private String readResourceFile(String fileName, String key) {
        try (InputStream is = new ClassPathResource(fileName).getInputStream();
             InputStreamReader reader = new InputStreamReader(is, StandardCharsets.UTF_8)) {
            ResourceBundle bundle = new PropertyResourceBundle(reader);
            return bundle.getString(key);
        } catch (Exception e) {
            // For detail lookups, we don't want to print stack trace as it's normal to not find some keys
            if (!key.contains(".detail")) {
                e.printStackTrace();
            }
        }
        return null;
    }
}
